#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>
#import <SpringBoard/SBApplicationController.h>
#import <SpringBoard/SBApplication.h>
#import <LockInfo/Plugin.h>
#import <EventKit/EKEventStore.h>

#import "framework/FWCommon.h"
#import "framework/FWPlugin.h"
#import "framework/FWApplication.h"
#import "framework/FWPopupView.h"

#import "PICommon.h"
#import "PIEventPlugin.h"
#import "PIIntegration.h"
#import "PIEventListAccess.h"
#import "PIEventStatus.h"
#import "PIAlarm.h"
#import "PIEvent.h"
#import "PIEventDebug.h"


static SystemSoundID const kSystemSoundID_Alarm = 1304; // ID for system alarm sound


@implementation PIEventPlugin

@synthesize eventStore, eventStoreUpdated, alarmDate, muteUntilDate;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

- (id)initWithApplication:(FWApplication*)app
{
    if ((self = [super initWithApplication:app name:@"PIEvent"])) {
        self.eventStore = [[[EKEventStore alloc] init] autorelease]; 
        self.fwDatasource = [[[PIEventListAccess alloc] init] autorelease];

        // Initialise alarm variables
        alarmSound = nil;
        lastDisplayWasLocked = NO;
        
        // Set default PI colors
        [PIIntegration updateInfoFromPrefs:[NSDictionary dictionary] application:app];
    }
    
    return self;
}

- (void)dealloc
{
    [eventStore release];
    [alarmDate release];
    [muteUntilDate release];

    if (alarmSound) {
        AudioServicesDisposeSystemSoundID(alarmSoundObject);
        CFRelease(alarmSoundURLRef);
    }
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Application status management

- (void)application:(FWApplication*)application updateApplicationPrefs:(NSDictionary*)prefs pluginPrefs:(FWPreferences*)pluginPrefs
{
}

- (BOOL)updateApplication:(FWApplication*)application
{
    if (!application.info)
        application.info = [[[PIEventStatus alloc] init] autorelease];

    BOOL response = [super updateApplication:application];

    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];

    // Notification sent when iOS events are updated
    [center addObserver:self selector:@selector(calendarUpdated:) name:@"EKEventStoreChangedNotification" object:eventStore];

//    [center addObserver:self
//               selector:@selector(notification:)
//                   name:nil
//                 object:nil];

    // Notification sent when iOS alarms are triggered
    [center addObserver:self selector:@selector(alarmFiredNotification:) name:@"kCalAlarmEngineAlarmsDidFireNotification" object:nil];

    // Notification when battery state changes
//    [center addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
//    [center addObserver:self selector:@selector(batteryStateChanged:) name:UIDeviceBatteryStateDidChangeNotification object:nil];

    // Get initial config
#ifdef DEBUG
    NSDictionary* prefs = [NSDictionary dictionaryWithContentsOfFile:application.preferencesPath];
    DebugLog(@"LI:PIEvent: PI Preferences on startup = %@", prefs);
#endif
    
    return response;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Update checking

- (BOOL)application:(FWApplication*)application shouldUpdateForDate:(NSDate*)date
{
    // Let the datasource handle update control
    return NO;
}


- (void)previewSelected:(LIAction *)action data:(LIData *)data
{
    if (![data.uniqueID isEqualToString:kUniqueIdInfo])
        [super previewSelected:action data:data];
    else if (self.isDebugMode) {
        PIEventDebug* alarms = [[[PIEventDebug alloc] initWithAlarms:((PIEventListAccess*)self.fwDatasource).additionalAlarms
                                                              events:self.currentItems] autorelease];
        FWDetailListView *thePreview = [[[FWDetailListView alloc] initWithFrame:[self previewCompatibleRect]
                                                                           list:[NSArray arrayWithObjects:@"X", nil]
                                                                          index:0
                                                                        caption:localize([NSBundle bundleForClass:[self class]], @"Debug View/Title")
                                                                    application:self.fwApplication
                                                                       delegate:alarms] autorelease];
        alarms.controlDelegate = thePreview;
        
        thePreview.backgroundColor = [UIColor whiteColor];
        [self.liPlugin showPreview:[self previewCompatibleView:thePreview]];
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Calendar database update callback

- (void)calendarUpdated:(NSNotification*)notif
{
    DebugLog(@"LI:PIEvent: iOS calendar update %@", notif);
    
    self.eventStoreUpdated = YES;
    [self triggerUnconditionalRefresh];
}

- (void)alarmFiredNotification:(NSNotification*)notif
{
    if (!self.liPlugin.enabled) {
        DebugLog(@"LI:PIEvent: Alarm fired notification - plugin disabled");
        return;
    }
    
    DebugLog(@"LI:PIEvent: Alarm fired notification ############ %@", notif);
    
    [self updateListForNotification];
}

#ifdef DEBUG
- (void)notification:(NSNotification*)notif
{
    DebugLog(@"LI:PIEvent: Notification ####################### %@; %@", notif.name, [notif.object class]);
}
#endif

- (void)application:(FWApplication *)application repeatingEventWithPluginPrefs:(FWPreferences *)prefs
{
    DebugLog(@"LI:PIEvent: Alarm sounding");
}

- (void)scheduleExtraAlarmForId:(NSString*)key atDate:(NSDate*)date type:(kPIEventAlarmType)type
{
    XLog(@"LI:PIEvent: Scheduling extra alarm at %@ for %@", date, key);
    
    [(PIEventListAccess*)self.fwDatasource scheduleExtraAlarmForId:key atDate:date type:type];
    
    // Will this be the new next alarm for the event?
    if (PIEvent* event = [self.currentItems piObjectForKey:key]) {
        NSDate* now = [NSDate date];
        if ([event.nextAlarm isEarlierThanDate:now] || [date isEarlierThanDate:event.nextAlarm])
            event.nextAlarm = date;
        XLog(@"LI:PIEvent: Extra alarm for event %@", event);
    }
    
    PIEventStatus* status = (PIEventStatus*)self.fwApplication.info;

    // Stop sounding the alarm if we still are
    if ([self.liPlugin isRepeatNotificationRegistered:self.notificationName]) {
        XLog(@"LI:PIEvent: Cancelled current repeat notification");
        [self.liPlugin cancelRepeatNotification:self.notificationName];
    }

    // If next alarm due is in the past then ignore it
    if (status.nextAlarmDue && [status.nextAlarmDue isEqualOrEarlierThanDate:[NSDate date]])
        status.nextAlarmDue = nil;

    if (!status.nextAlarmDue || [date isEarlierThanDate:status.nextAlarmDue]) {
        XLog(@"LI:PIEvent: Extra alarm is earlier than next alarm at %@", status.nextAlarmDue);
        status.nextAlarmDue = date;
    }
#ifdef DEBUG
    else
        XLog(@"LI:PIEvent: Extra alarm is later than next alarm at %@ - no action required", status.nextAlarmDue);
#endif
    
    if (status.nextChangeDue || [date isEarlierThanDate:status.nextChangeDue]) {
        XLog(@"LI:PIEvent: Extra alarm is earlier than next wakeup %@", status.nextChangeDue);
        //status.nextChangeDue = date;
        
        [self scheduleNextTimerEvent:date];
    }
#ifdef DEBUG
    else
        XLog(@"LI:PIEvent: Extra alarm is later than next wakeup %@ no action required", status.nextChangeDue);
#endif
}         

- (NSDate*)reminderEndTimeForEvent:(PIEvent*)event startTime:(NSDate*)start
{
    XLog(@"LI:PIEvent: Calculating reminder end time for start time %@", start);

    BOOL alertPastEvent = [FWPreferences boolValue:kPIOptionsIsAlertDuringEvent
                                       withDefault:kPIOptionsIsAlertDuringEventDefault
                                       preferences:self.liPlugin.preferences];
    DebugLog(@"LI:PIEvent: Alerts past event start = %d", alertPastEvent);

    if ([start isEqualOrLaterThanDate:event.startDate] && !alertPastEvent) {
        XLog(@"LI:PIEvent: Start time later than event time %@ so no reminder", event.startDate);
        return nil;
    }

    NSInteger repeatDuration = [FWPreferences intValue:kPIOptionsRepeatAlertDuration
                                           withDefault:kPIOptionsRepeatAlertDurationDefault
                                           preferences:self.liPlugin.preferences];
    DebugLog(@"LI:PIEvent: Default alert duration = %d secs", repeatDuration);

    NSDate* result = [start addTimeInterval:repeatDuration];
    if ([result isEqualOrLaterThanDate:event.startDate]) {
        XLog(@"LI:PIEvent: Standard end time %@ later than event %@ so using event time", result, event.startDate);
        return event.startDate;
    }
    
    XLog(@"LI:PIEvent: Calculated standard end time %@", result);
    return result;
}

// ******************************************************************************************
#pragma mark -
#pragma mark Toolbar button callbacks

- (void)removeActiveAlarm:(PIEvent*)event
{
    // Remove the alarm active entries from the control tables
    event.reminderInteract = NO;
    PIAlarm* alarm = [((PIEventListAccess*)self.fwDatasource).additionalAlarms piAlarmForKey:event.key
                                                                                      type:kPIEventAlarmTypeAlarmIsActive];
    [alarm expireAlarm];
}

- (void)closeMenu:(UIBarButtonItem*)sender update:(BOOL)update
{
    if (self.isToolbarVisible) {
        if (update)
            [self setToolbarIndex:-1 updatingRow:self.toolbarIndex - 1];
        else
            [self hideToolbar];
    }
}

- (void)displayPopupMessage:(NSString*)msg
{
    // Don't show if popups are disabled
    if (![FWPreferences boolValue:kPIOptionsShowPopups withDefault:kPIOptionsShowPopupsDefault preferences:self.liPlugin.preferences])
        return;
    
    UIView* view = FWLITableView();
    if (view)
        [FWPopupView displayPopupMessage:msg forView:view];
}

- (void)closeMenuClicked:(UIBarButtonItem*)sender
{
    [self closeMenu:sender update:NO];
}

- (void)sleepAlarmClicked:(UIBarButtonItem*)sender
{
    PIEvent* event = [self.currentItems objectAtIndex:self.toolbarIndex - 1];
    
    // Add an extra alarm sound at the due time of the alarm
    [self scheduleExtraAlarmForId:event.key atDate:event.startDate type:kPIEventAlarmTypeExtraAlarm];
    [self removeActiveAlarm:event];
    
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    NSString* msg = [NSString stringWithFormat:localize(bundle, @"Status/Alarm/Sleeping"),
                     FWLocalDateStringForUTCDate(event.startDate, FWDateFormatterTimeOnlyFormat, YES, bundle)];
    [self displayPopupMessage:msg];

    [self closeMenu:sender update:YES];
}

- (void)snoozeAlarmClicked:(UIBarButtonItem*)sender
{
    PIEvent* event = [self.currentItems objectAtIndex:self.toolbarIndex - 1];
    
    NSInteger period = [FWPreferences intValue:kPIOptionsSnoozeAlertDuration
                                   withDefault:kPIOptionsSnoozeAlertDurationDefault
                                   preferences:self.liPlugin.preferences];
    XLog(@"LI:PIEvent: Snooze period = %d", period);

    // Is it a percentage of the remaining?
    if (period < 0) {
        period = [event.startDate timeIntervalSinceNow] * (abs(period) / 100);
        XLog(@"LI:PIEvent: Snooze calculated from time remaining to %@ = %d", event.startDate, period);
    }
    
    // Add an extra reminder sound at the snooze interval
    NSDate* snoozeDate = [[NSDate date] addTimeInterval:period];

    [self scheduleExtraAlarmForId:event.key atDate:snoozeDate type:kPIEventAlarmTypeExtraReminder];
    [self removeActiveAlarm:event];

    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    NSString* msg = [NSString stringWithFormat:localize(bundle, @"Status/Alarm/Sleeping"),
                     FWLocalDateStringForUTCDate(snoozeDate, FWDateFormatterTimeOnlyFormat, YES, bundle)];
    [self displayPopupMessage:msg];

    [self closeMenu:sender update:YES];
}

- (void)cancelAlarmClicked:(UIBarButtonItem*)sender
{
    PIEvent* event = [self.currentItems objectAtIndex:self.toolbarIndex - 1];
    
    [self displayPopupMessage:localize([NSBundle bundleForClass:[self class]], @"Status/Alarm/Cancelled")];

    [self cancelAlarmSound];
    [self removeActiveAlarm:event];

    [self closeMenu:sender update:YES];
}

- (void)muteAlarmClicked:(UIBarButtonItem*)sender
{
    PIEvent* event = [self.currentItems objectAtIndex:self.toolbarIndex - 1];

    // Mute the alarm until the expiry date of the current alarm indication
    NSDate* muteDate = event.startDate;
    PIAlarm* alarm = [((PIEventListAccess*)self.fwDatasource).additionalAlarms piAlarmForKey:event.key
                                                                                      type:kPIEventAlarmTypeAlarmIsActive];
    if (alarm)
        muteDate = alarm.date;

    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    NSString* msg = [NSString stringWithFormat:localize(bundle, @"Status/Alarm/Muted"),
                     FWLocalDateStringForUTCDate(muteDate, FWDateFormatterTimeOnlyFormat, YES, bundle)];
    [self displayPopupMessage:msg];

    [self muteAlarmUntilDate:muteDate];
    
    [self closeMenu:sender update:NO];
}

- (void)unmuteAlarmClicked:(UIBarButtonItem*)sender
{
    [self muteAlarmUntilDate:nil];
    [self closeMenu:sender update:NO];
    
    [self displayPopupMessage:localize([NSBundle bundleForClass:[self class]], @"Status/Alarm/Unmuted")];
}

- (void)showPreviewClicked:(UIBarButtonItem*)sender
{
    FWDetailListView *preview = [(PIEventListAccess*)self.fwDatasource previewWithFrame:[self previewCompatibleRect]
                                                                              atIndex:self.toolbarIndex - 1
                                                                             forItems:self.currentItems
                                                                          application:self.fwApplication];

    if (preview) {
        [self closeMenu:sender update:NO];
        [self.liPlugin showPreview:[self previewCompatibleView:preview]];
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Battery monitoring

- (void)batteryStateChanged:(NSNotification*)notif
{
    
}

- (void)batteryLevelChanged:(NSNotification*)notif
{
    
}


// ******************************************************************************************
#pragma mark -
#pragma mark Alarm support

- (void)muteAlarmUntilDate:(NSDate*)date
{
    if (date) {
        XLog(@"LI:PIEvent: Muting alarm until %@", date);
        [muteUntilDate release];
        muteUntilDate = [date retain];
    }
    else if (muteUntilDate) {
        XLog(@"LI:PIEvent: Cancelling alarm mute mode");
        [muteUntilDate release];
        muteUntilDate = nil;
    }
}

- (void)scheduleAlarmSound:(NSString *)sound forDate:(NSDate *)date withItem:(PIEvent*)item playNow:(BOOL)play
{
    NSTimeInterval duration = (int)[item.startDate timeIntervalSinceDate:date];
    
    [self scheduleAlarmSound:sound
                     forDate:date 
                    duration:duration
                     playNow:play];
}

- (void)scheduleAlarmSound:(NSString*)sound forDate:(NSDate*)date duration:(NSTimeInterval)duration playNow:(BOOL)play
{
    if (alarmDate && [alarmDate isEqualToDate:date]) {
        DebugLog(@"LI:PIEvent: Scheduling duplicate alarm time - ignored");
        return;
    }

    // Remove old reference
    if (alarmSound) {
        AudioServicesDisposeSystemSoundID(alarmSoundObject);
        CFRelease(alarmSoundURLRef);
        alarmSound = nil;
        
        [alarmDate release];
        alarmDate = nil;

        DebugLog(@"LI:PIEvent: Released sound ID %lu", alarmSoundObject);
    }

    if (duration <= 0) {
        XLog(@"LI:PIEvent: Negative duration - no alarm scheduled");
        return;
    }
    
    // Save the alarm date so we can ignore duplicate alarms
    alarmDate = [date retain];
    
    // Cancel mute mode
    [self muteAlarmUntilDate:nil];
    
    if (sound.length > 0) {
//        NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Audio/UISounds"];
//#ifdef DEVELOPMENT_MODE
//        bundle = [NSBundle bundleForClass:[self class]];
//#endif

        alarmSound = [[PIIntegration alarmSoundURL:self.fwApplication alarm:sound] retain];
        DebugLog(@"LI:PIEvent: Alarm sound file URL = %@", alarmSound);
        
        // Store the URL as a CFURLRef instance
        alarmSoundURLRef = (CFURLRef)alarmSound;
        
        // Create a system sound object representing the sound file.
        AudioServicesCreateSystemSoundID(alarmSoundURLRef, &alarmSoundObject);
        
        DebugLog(@"LI:PIEvent: Created sound ID = %lu", alarmSoundObject);
    }

    FWPreferences* prefs = [FWPreferences preferencesWithDictionary:self.liPlugin.preferences];
    BOOL vibrate = [prefs boolValue:kPIOptionsVibrateOnAlert withDefault:kPIOptionsVibrateOnAlertDefault];
    BOOL wake = [prefs boolValue:kPIOptionsWakeOnAlert withDefault:kPIOptionsWakeOnAlertDefault];
    NSTimeInterval interval = [prefs intValue:kPIOptionsRepeatAlertInterval withDefault:kPIOptionsRepeatAlertIntervalDefault];
    
    if (play) {
        if (vibrate)
            AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
        
        if (alarmSound) {
            XLog(@"LI:PIEvent: Playing sound %lu", alarmSoundObject);
            AudioServicesPlaySystemSound(alarmSoundObject);
        }
        else {
            XLog(@"LI:PIEvent: Playing system alarm %lu", alarmSoundObject);
            AudioServicesPlaySystemSound(kSystemSoundID_Alarm);
        }
    }
    
    XLog(@"LI:PIEvent: Scheduled reminder; interval = %f; duration = %f; wake = %i", interval, duration, wake); 
    
    [self.liPlugin registerRepeatNotification:self.notificationName
                                     interval:interval
                                     duration:duration
                                         wake:wake
                                     userInfo:[NSDictionary dictionary]];
}

- (void)cancelAlarmSound
{
    [self.liPlugin cancelRepeatNotification:self.notificationName];

    [alarmDate release];
    alarmDate = nil;

    [self muteAlarmUntilDate:nil];
}

- (BOOL)isAlarmSoundScheduled
{
    return [self.liPlugin isRepeatNotificationRegistered:self.notificationName];
}

- (void)repeatingEventNotification:(NSNotification*)notification;
{
    if (alarmSound) {
        // Mute if the mute until date is not less than the current date
        BOOL mute = muteUntilDate && [muteUntilDate isLaterThanDate:[NSDate date]];

        if (mute)
            XLog(@"LI:PIEvent: Alarm is muted - not sounding");
        
        BOOL vibrate = [FWPreferences boolValue:kPIOptionsVibrateOnAlert
                                    withDefault:kPIOptionsVibrateOnAlertDefault
                                    preferences:self.liPlugin.preferences];

        if (mute || vibrate)
            AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
        
        if (!mute) {
            XLog(@"LI:PIEvent: Playing sound");
            AudioServicesPlaySystemSound(alarmSoundObject);
        }
    }
    else
        XLog(@"LI:PIEvent: No sound registered - doing nothing");
}

// Triggered when a scheduled event occurs. Called with the actual time the event
// was scheduled.
- (void)scheduledEventNotification:(NSDate *)scheduledDate
{
    XLog(@"LI:PIEvent: Scheduled Wakeup Notification #######################");

    // Retain a copy of the extra alarms list in case it changes while we are working
    NSArray* extraAlarms = [((PIEventListAccess*)self.fwDatasource).additionalAlarms retain];
    
    // See if we have an extra alarm we want to trigger
    for (PIAlarm* extraAlarm in extraAlarms) {
        if ([extraAlarm.date isEqualToDate:scheduledDate]) {
            XLog(@"LI:PIEvent: Found additional item waiting for trigger %@", extraAlarm);

            if (extraAlarm.type == kPIEventAlarmTypeExtraAlarm) {
                XLog(@"LI:PIEvent: Sounding additional alarm");

                BOOL vibrate = [FWPreferences boolValue:kPIOptionsVibrateOnAlert
                                            withDefault:kPIOptionsVibrateOnAlertDefault
                                            preferences:self.liPlugin.preferences];
                if (vibrate)
                    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                AudioServicesPlaySystemSound(kSystemSoundID_Alarm);
            }                
            else if (extraAlarm.type == kPIEventAlarmTypeExtraReminder) {
                if (PIEvent* event = [self.currentItems piObjectForKey:extraAlarm.key]) {
                    XLog(@"LI:PIEvent: Sounding additional reminder for event %@", event);
                
                    NSString* alarmType = [FWPreferences stringValue:kPIOptionsRepeatAlertSound 
                                                         withDefault:kPIOptionsRepeatAlertSoundDefault
                                                         preferences:self.liPlugin.preferences];
                    [self scheduleAlarmSound:alarmType forDate:scheduledDate withItem:event playNow:YES];
                }
            }                
        }
    }

    [extraAlarms release];
}

- (void)checkForNewAlarmsForDate:(NSDate*)date
{
    XLog(@"LI:PIEvent: Checking for new alarms to monitor for date %@", date);
    
    PIEvent* triggeredEvent = nil;
    NSArray* items = [self.currentItems retain];
    for (PIEvent* event in items) {
        // Is this a newly triggered alarm?
        if ([event.nextAlarm isEqualToDate:date]) {
            XLog(@"LI:PIEvent: Found newly triggered alarm %@", event.shortDescription);
            
            // Add a marker so we remember this alarm is active
            if (NSDate* end = [self reminderEndTimeForEvent:event startTime:date]) {
                [self scheduleExtraAlarmForId:event.key atDate:end type:kPIEventAlarmTypeAlarmIsActive];
                event.reminderInteract = YES;
                triggeredEvent = event;
            }
        }
    }
    [items release];
    
    if (triggeredEvent) {
        NSString* alarm = [FWPreferences stringValue:kPIOptionsRepeatAlertSound
                                         withDefault:kPIOptionsRepeatAlertSoundDefault
                                         preferences:self.liPlugin.preferences];
        
        if (NSDate* end = [self reminderEndTimeForEvent:triggeredEvent startTime:date]) {
            NSDate* now = [NSDate date];
            NSTimeInterval duration = [end timeIntervalSinceDate:now];
            
            XLog(@"LI:PIEvent: New alarm detected - scheduling reminder alarm, end = %@, duration = %f", end, duration);
            [self scheduleAlarmSound:alarm
                             forDate:now
                            duration:duration
                             playNow:NO];
        }
    }
}

- (void)notifyNextTimerEventDate:(NSDate*)date
{
}

// ******************************************************************************************
#pragma mark -
#pragma mark Managing the toolbar bar

- (NSArray*)toolbarItems
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];

    BOOL mute = muteUntilDate && [muteUntilDate isLaterThanDate:[NSDate date]];
    
    UIBarButtonItem* closeBtn = [[[UIBarButtonItem alloc]
                                  initWithImage:[UIImage imageWithContentsOfFile:[bundle pathForResource:@"menuclose" ofType:@"png"]]
                                  style:UIBarButtonItemStylePlain
                                  target:self
                                  action:@selector(closeMenuClicked:)] autorelease];
    
    UIBarButtonItem* snoozeBtn = [[[UIBarButtonItem alloc]
                                   initWithImage:[UIImage imageWithContentsOfFile:[bundle pathForResource:@"snooze" ofType:@"png"]]
                                   style:UIBarButtonItemStylePlain
                                   target:self
                                   action:@selector(snoozeAlarmClicked:)] autorelease];
    
    UIBarButtonItem* sleepBtn = [[[UIBarButtonItem alloc]
                                  initWithImage:[UIImage imageWithContentsOfFile:[bundle pathForResource:@"sleep" ofType:@"png"]]
                                  style:UIBarButtonItemStylePlain
                                  target:self
                                  action:@selector(sleepAlarmClicked:)] autorelease];
    
    UIBarButtonItem* muteBtn = [[[UIBarButtonItem alloc]
                                 initWithImage:[UIImage imageWithContentsOfFile:
                                                [bundle pathForResource:mute ? @"nomute" : @"mute" ofType:@"png"]]
                                 style:UIBarButtonItemStylePlain
                                 target:self
                                 action:mute ? @selector(unmuteAlarmClicked:) : @selector(muteAlarmClicked:)] autorelease];
    
    UIBarButtonItem* cancelBtn = [[[UIBarButtonItem alloc]
                                   initWithImage:[UIImage imageWithContentsOfFile:[bundle pathForResource:@"cancel" ofType:@"png"]]
                                   style:UIBarButtonItemStylePlain
                                   target:self
                                   action:@selector(cancelAlarmClicked:)] autorelease];
    
    UIBarButtonItem* previewBtn = [[[UIBarButtonItem alloc]
                                    initWithImage:[UIImage imageWithContentsOfFile:[bundle pathForResource:@"view2" ofType:@"png"]]
                                    style:UIBarButtonItemStylePlain
                                    target:self
                                    action:@selector(showPreviewClicked:)] autorelease];
    
    UIBarButtonItem *flexSpc = [[[UIBarButtonItem alloc]
                                 initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                 target:nil
                                 action:nil] autorelease];
    UIBarButtonItem *fixedSpc = [[[UIBarButtonItem alloc]
                                  initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                                  target:nil
                                  action:nil] autorelease];
    fixedSpc.width = 10;
    
    NSMutableArray* menu = [NSMutableArray arrayWithObjects:
                            closeBtn, flexSpc, fixedSpc, flexSpc,
                            snoozeBtn, flexSpc,
                            muteBtn, flexSpc,
                            sleepBtn, flexSpc,
                            cancelBtn, flexSpc, fixedSpc, flexSpc,
                            nil];
    
    if ([FWPreferences boolValue:kPIOptionsShowPreviews withDefault:kPIOptionsShowPreviewsDefault preferences:self.liPlugin.preferences]) {
        [menu addObject:previewBtn];
        [menu addObject:flexSpc];
    }

    
    return menu;
}

- (BOOL)configureToolbarItems:(NSArray *)items
{
    return YES;
}

- (void)screenUndimmedNotification:(NSNotification*)notif
{
    if (self.fwApplication.isLockScreen &&
        !lastDisplayWasLocked && 
        ![FWPreferences boolValue:kPIOptionsLockDetails
                      withDefault:kPIOptionsLockDetailsDefault
                      preferences:self.liPlugin.preferences]) {
            NSLog(@"LI:%@: Redisplaying all events to remove location on lock screen", self.resourceName);
            self.shouldRedisplayOnNextUpdate = YES;
        }
    
    [super screenUndimmedNotification:notif];
}

- (CGFloat)viewHeightForData:(LIData *)data withWidth:(CGFloat)width
{
    lastDisplayWasLocked = self.fwApplication.isLockScreen;
    return [super viewHeightForData:data withWidth:width];
}

@end
